<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .box{
            display: flex;
        }
        .box p{
            width: 50px;
            height: 50px;
            border: 1px solid #ccc;
            border-radius: 20px;
            box-sizing: border-box;
            line-height: 50px;
            text-align: center;
            margin-right: 16px;
            cursor: pointer;
        }
        .box p{
            -webkit-user-select: none; /* Safari */
            -moz-user-select: none; /* Firefox */
            -ms-user-select: none; /* IE10+/Edge */
            user-select: none; /* 标准语法 */
        }
    </style>
</head>
<body>
    <div class="box"></div>
</body>
<script>
    let arr = [1,2,3,4,5];
    let box = document.querySelector('.box');
    
    arr.forEach(el=>{
        let dom = document.createElement('p');
        dom.innerText = el;
        // 怎样让元素变得可拖拽
        // 给元素加上 draggable 属性，值为 true 即可
        dom.setAttribute('draggable',true)
        box.appendChild(dom);
    });

    window.onload = ()=>{
        // 拖拽排序在很多站点里面是非常常见的，使用的API就是一个拖拽API
        
        // 1、让元素变的可拖拽   找到这些元素，给这些元素加上 draggable 属性，值为true，这样就变得可拖拽了
        // 2、拖拽的时候样式得变   class为moving的样式
        const list = document.querySelector('.box')
        
        // 用事件委托的方式 给父元素绑定事件
        list.addEventListener('dragstart', function (e) {
            // 当拖拽开始的时候要找到拖拽的那个元素给他添加类样式

            // 为什么要用setTimeout,不用的话拖拽的那个元素也会变成虚线（就是添加了类样式后的样子），
            // 它的样式取决于拖拽开始时候元素本身的样式，需要在拖拽开始的时候保持原来的样式 把它变成异步的
            setTimeout(() => {
                e.target.classList.add('moving')
            }, 0)
            sourceNode = e.target
        })
        // 用来记录当前拖拽的是哪个元素
        let sourceNode = null

        // 3、什么时候产生排序？拖拽的时候把拖拽对象放到了某些元素之上，这里就要监听拖拽进入事件
        list.addEventListener('dragenter', function (e) {
            e.preventDefault()
            // 排除掉一些情况，比如拖拽的时候进入了父元素 或者 是本身自己
            if (e.target == list || e.target == sourceNode) return
            const children = [...list.children]
            // 通过所处元素的下标来判断是左边还是右边
            const sourceIndex = children.indexOf(sourceNode)
            const targetIndex = children.indexOf(e.target)
            // 4、当拖拽的元素进入到别的元素身上的时候，要做的一些事情
            if (sourceIndex < targetIndex) {
                console.log('右边')
                // 插入到那个元素下一个元素之前
                list.insertBefore(sourceNode, e.target.nextElementSibling)
            } else {
                console.log('左边')
                list.insertBefore(sourceNode, e.target)
            }
        })

        // 拖拽完毕 松开鼠标
        list.addEventListener('dragend', function (e) {
            // 移除掉类样式即可
            sourceNode.classList.remove('moving')
        })
    }
</script>
</html>